package com.lonely.fx.image;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

/**
 * @date: 2022-07-26 18:46
 * @author: ztkj-hzb
 * @description: 取色器设置--读取图片像素
 **/
public class PixelReaderSettingMain extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    /**
     * 像素的组成：看是32位还是24位， 一般png是32位，jpg是24位，区别在于对于透明像素处理，png表现为透明，jpg表现为白色
     * Argb: Alpha:透明度  Red  Green  Blue 等组成,每个元素占用1个字节，即8位
     */
    @Override
    public void start(Stage primaryStage) throws Exception {

        HBox hBox = new HBox();

        Image image = new Image("icons/sc01.png");
        ImageView imageView = new ImageView(image);

        //获取像素读取器
        PixelReader pixelReader = image.getPixelReader();

        //获取指定位置的像素的argb值，
        int argb = pixelReader.getArgb(0, 0);
        System.out.println(argb);

        int alpha = argb >> 24 & 0xff;
        int red = argb >> 16 & 0xff;
        int green = argb >> 8 & 0xff;
        int blue = argb & 0xff;

        System.out.println("透明度:" + alpha);
        System.out.println("red:" + red);
        System.out.println("green" + green);
        System.out.println("blue:" + blue);

        System.out.println("-----------------------------------------------------------");

        //获取指定像素对应的颜色
        Color color = pixelReader.getColor(0, 0);
        System.out.println("透明度:" + color.getOpacity() * 255);
        System.out.println("red:" + color.getRed() * 255);
        System.out.println("green:" + color.getGreen() * 255);
        System.out.println("blue:" + color.getBlue() * 255);

        System.out.println("-----------------------------------------------------------");

        //也可以通过color.toString()的返回值中解析出argb
        String colorStr = color.toString();

        //ColorString的组成：举例：0x6e7758ff   0x----没有用，  6e----红色 77----绿色  58----蓝色 ff----透明度
        colorStr = colorStr.substring(2);
        System.out.println("透明度:" + Integer.parseInt(colorStr.substring(6, 8), 16));
        System.out.println("red:" + Integer.parseInt(colorStr.substring(0, 2), 16));
        System.out.println("green:" + Integer.parseInt(colorStr.substring(2, 4), 16));
        System.out.println("blue:" + Integer.parseInt(colorStr.substring(4, 6), 16));

        System.out.println("-----------------------------------------------------------");


        //TODO 批量读取指定区间范围的像素信息集合---使用byte[] 接收
        WritablePixelFormat<ByteBuffer> byteBgraPreInstance = PixelFormat.getByteBgraPreInstance();
        //这里为什么要 * 4 因为用byte接收，每个像素对应32位--4字节
        byte[] bytes = new byte[10 * 10 * 4];
        // offset：buffer中用于存储第一个像素数据的偏移量，一般是0
        // scanlineStride – 缓冲区中一行数据开头的像素数据到下一行数据开头的距离
        //执行完毕后，指定范围内的数据已经保存到 bytes 中了
        pixelReader.getPixels(0, 0, 10, 10, byteBgraPreInstance, bytes, 0, 10 * 4);

        //解析数据, 每4个字节一解析,代表一个像素数据
        for (int i = 0; i < bytes.length; i += 4) {
            //System.out.println("blue:" + (bytes[i] & 0xff));
            //System.out.println("green:" + (bytes[i + 1] & 0xff));
            //System.out.println("red:" + (bytes[i + 2] & 0xff));
            //System.out.println("透明度:" + (bytes[i + 3] & 0xff));
        }

        System.out.println("-----------------------------------------------------------");


        //TODO 批量读取指定区间范围的像素信息集合---使用int[] 接收
        WritablePixelFormat<IntBuffer> intArgbPreInstance = PixelFormat.getIntArgbPreInstance();
        int[] intBuffs = new int[10 * 10];
        //执行完后，数据保存到了 int[] 中
        pixelReader.getPixels(0, 0, 10, 10, intArgbPreInstance, intBuffs, 0, 10);

        for (int i = 0; i < intBuffs.length; i++) {
            //System.out.println("透明度:" + (intBuffs[i] >> 24 & 0xff));
            //System.out.println("red:" + (intBuffs[i] >> 16 & 0xff));
            //System.out.println("green" + (intBuffs[i] >> 8 & 0xff));
            //System.out.println("blue:" + (intBuffs[i] & 0xff));
        }

        System.out.println("-----------------------------------------------------------");

        //获取图片类型
        PixelFormat.Type type = pixelReader.getPixelFormat().getType();
        System.out.println("图片类型：" + type);

        hBox.getChildren().addAll(imageView);
        primaryStage.setScene(new Scene(hBox));
        primaryStage.setWidth(600);
        primaryStage.setHeight(500);
        primaryStage.show();

    }
}
